package org.example.spring.repository.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.example.spring.repository.service.IClientService;
import org.example.spring.utils.TransactionThreadHolder;
import org.example.spring.utils.TransactionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;

/**
 * LuoYu
 * 2022/12/13 18:51
 **/
@Service
@Slf4j
public class TransactionClientServiceImpl implements IClientService {

    @Autowired
    private PlatformTransactionManager transactionManager;




    @Override
    public void required() {
        boolean hasExist = TransactionThreadHolder.hasExist();
        // 判断当前线程中是否存在事务，没有就新开一个
        if(!hasExist) {
            TransactionThreadHolder.add(TransactionUtil.getTransactionStatus());
        }
        try {
            // 执行sql语句
            // insert   update   delete
            // 如果是当前线程新开事务，直接提交
            if(!hasExist) {
                transactionManager.commit(TransactionThreadHolder.get());
            }
        }catch (Exception e) {
            // 如果是当前线程新开事务,直接回滚
            if(!hasExist) {
                transactionManager.rollback(TransactionThreadHolder.get());
            } else {
                // 如果不是，则直接交给存在的事务进行回滚
                throw e;
            }
        }finally {
            // 如果是当前线程新开事务,删除事务实例
            if(!hasExist) {
                TransactionThreadHolder.remove();
            }
        }



    }

    @Override
    public void supports() {
        // 这种事务方式啥都不干，当前线程有事务，就加入事务，抛出的异常也会被调用方接收到执行回滚
        // 执行sql语句
        // insert   update   delete
    }

    @Override
    public void requiredWithSupport() {

    }

    @Override
    public void mandatory() {
        boolean hasExist =  TransactionThreadHolder.hasExist();
        // 不存在事务，抛出异常
        if(!hasExist) {
            throw new RuntimeException("mandatory 不存在事务，抛出异常");
        }
        // 到了这里啥都不干,加入事务一起执行，抛出的异常也会被调用方接收到执行回滚
        // 执行sql语句
        // insert   update   delete
    }

    @Override
    public void requiredWitchMandatory() {

    }

    @Override
    public void requiredNew() {
        boolean hasExist =  TransactionThreadHolder.hasExist();
        // 当前存在事务，挂起事务
        if(hasExist) {
            new Thread(() -> {
                TransactionThreadHolder.add(TransactionUtil.getTransactionStatus());
                try {
                    // SQL  insert delete update
                transactionManager.commit(TransactionThreadHolder.get());
                }catch (Exception e) {
                    transactionManager.rollback(TransactionThreadHolder.get());
                }finally {
                    TransactionThreadHolder.remove();
                }
            });
        } else {
            // 走required逻辑
            required();
        }
    }

    @Override
    public void requiredWitchRequiredNew(boolean hasThrow) {

    }

    @Override
    public void never() {
        boolean hasExist =  TransactionThreadHolder.hasExist();
        if(hasExist) {
            throw new RuntimeException("never 禁用事务，抛出异常");
        }
    }

    @Override
    public void requiredWithNever() {

    }

    @Override
    public void nested() {

    }

    @Override
    public void requiredNested(boolean hasThrow) {

    }
}
